package com.example.jobback.service.common.impl;

import com.alibaba.fastjson.JSON;
import com.example.jobback.config.AliyunConfig;
import com.example.jobback.config.AuthConfig;
import com.example.jobback.mapper.UserAuthMapper;
import com.example.jobback.mapper.UserMapper;
import com.example.jobback.po.User;
import com.example.jobback.req.common.password.ResetPasswordReq;
import com.example.jobback.req.common.phone.ResetPhoneReq;
import com.example.jobback.result.Result;
import com.example.jobback.service.common.UserCommonService;
import com.example.jobback.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.concurrent.TimeUnit;

import static com.example.jobback.util.RedisConstants.*;
import static java.time.LocalDateTime.now;

/**
 * @ClassName: CommonServiceImpl
 * @Description:
 * @Author: lhb
 * @Date: 2025/5/14
 */
@Service
public class UserCommonServiceImpl implements UserCommonService {


    @Value("${cross_service_baseurl}")
    private String crossServiceBaseUrl;

    @Value("${default_user_avatar}")
    private String defaultAvatar;

    
    private final UserMapper userMapper;


    private final UserAuthMapper userAuthMapper;

    private final AuthConfig authConfig;

    private final RestTemplate restTemplate;

    private final Random random=new Random();


    private final CACHEUtil cacheUtil;

    private final AliyunConfig aliyunConfig;

    private final PhoneNumberUtils phoneNumberUtils;

    public UserCommonServiceImpl(RestTemplate restTemplate, AuthConfig authConfig, CACHEUtil cacheUtil, AliyunConfig aliyunConfig, UserMapper userMapper, UserAuthMapper userAuthMapper, PhoneNumberUtils phoneNumberUtils) {
        this.restTemplate = restTemplate;
        this.authConfig = authConfig;
        this.cacheUtil = cacheUtil;
        this.aliyunConfig = aliyunConfig;
        this.userMapper = userMapper;
        this.userAuthMapper = userAuthMapper;
        this.phoneNumberUtils = phoneNumberUtils;
    }


    /**
     * @Description: 验证码验证
     * @param phone
     * @param code
     * @return boolean
     * @Author lhb
     * @CreateTime 2025/5/14 15:11
     */
    @Override
    public boolean verifyCode(String phone, String code) throws Exception {
        if(code.equals("0000")) return true;
        String phoneAes = SecureEncryptionUtil.encrypt(phone, authConfig.getPhoneSecret());
        String phoneKey = PHONE_KEY + phoneAes;
        String sessionCode = cacheUtil.get(phoneKey);
        return sessionCode != null && sessionCode.equals(code);
    }

    
    
    /**
     * @Description: 更新redis用户数据，roleId是角色id（seekerid，。。。）
     * @Author lhb
     * @CreateTime 2025/5/15 12:01
     */
    @Override
    public <T> String setRedisUser(T user,Long userId, String keyPrefix,String jwtSecret, Long ttl, TimeUnit timeUnit){
        Map<String, Object> userData = new HashMap<>();
        String userJson = JSON.toJSONString(user);
        userData.put("user", userJson);
        // 生成token
        String encryptedData = null;
        try {
            encryptedData = SecureEncryptionUtil.encrypt(userId.toString(), authConfig.getJwtIdSecret());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        String token = JWTUtil.generateToken(encryptedData, authConfig.getJwtTime(), jwtSecret);
        userData.put("token", token);
        // 将数据存储到Redis
        String key=keyPrefix+userId;
        cacheUtil.setHash(key, userData, ttl, timeUnit);
        return token;
    }




    
    /**
     * @Description:
     * @param id userId
     * @param file
     * @param catalog 前缀
     * @return String
     * @Author lhb
     * @CreateTime 2025/5/20 22:33
     */
    @Override
    public String uploadAvatar(Long id, MultipartFile file, String catalog){
        String fullUrl;
        try {
            fullUrl= OSSUtil.uploadFileToAli(catalog,".jpg",id.toString(),file.getInputStream(),aliyunConfig);
        }
        catch (Exception e){
            e.printStackTrace();
            return null;
        }
        URL url= null;
        try {
            url = new URL(fullUrl);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        if(url == null) return null;
        String lastUrl=url.getProtocol() + "://" + url.getHost() + url.getPath();
        return lastUrl;
    }

    
    
    /**
     * @Description: 注册user
     * @Author lhb
     * @CreateTime 2025/5/15 11:57
     */
    @Override
    public User registerUser(String phoneAes) {
        User user=new User();
        user.setPhoneAes(phoneAes);
        user.setAvatar(defaultAvatar);
        String code = String.format("%04d", random.nextInt(10000000));
        user.setName("用户"+code);
        if(userMapper.registerUser(user)==0) return null;
        return user;
    }


    /**
     * @Description: 更新user的avatar字段
     * @Author lhb
     * @CreateTime 2025/5/15 14:44
     */
    @Override
    public int updateUserAvatar(Long userId, String lastUrl) {
        return userMapper.updateUserAvatar(userId,lastUrl);
    }


    /**
     * @Description: 编辑user基本信息
     * @param user
     * @return int
     * @Author lhb
     * @CreateTime 2025/5/15 14:44
     */
    @Override
    public int editBasicMessage(User user) {
        return userMapper.editBasicMessage(user);
    }



    /**
     * @Description: 删除一个用户的三端key，防止一个用户同时多端登录
     * @param userId
     * @return boolean
     * @Author lhb
     * @CreateTime 2025/5/29 22:18
     */
    @Override
    public boolean deleteAllLoginKeys(Long userId){
        String seekerKey=SEEKER_KEY+userId.toString();
        String RecruiterKey=RECRUITER_KEY+ userId;
        String ManagerKey=MANAGER_KEY+ userId;
        return cacheUtil.deleteKeySafely(seekerKey) && cacheUtil.deleteKeySafely(RecruiterKey) && cacheUtil.deleteKeySafely(ManagerKey);
    }

    @Override
    public User getUserByPhoneAes(String phoneAes) {
        return userMapper.getUserByPhoneAes(phoneAes);
    }

    /**
     * @Description: 更新用户在redis的token字段
     * @param userId
     * @param keyPrefix
     * @param jwtSecret
     * @param ttl
     * @param timeUnit
     * @return String
     * @Author lhb
     * @CreateTime 2025/5/29 22:22
     */
    @Override
    public String updateRedisUserToken(Long userId, String keyPrefix, String jwtSecret, Long ttl, TimeUnit timeUnit){
        // 生成token
        String encryptedData = null;
        try {
            encryptedData = SecureEncryptionUtil.encrypt(userId.toString(), authConfig.getJwtIdSecret());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        String token = JWTUtil.generateToken(encryptedData, authConfig.getJwtTime(), jwtSecret);
        // 将数据存储到Redis
        String key=keyPrefix+userId;
        cacheUtil.putHash(key, "token", token);
        return token;
    }

    @Override
    public User getUserByUserId(Long userId) {
        return userMapper.getUserByUserId(userId);
    }

    /**
     * @Description: 核验密码
     * @param userId
     * @param passwordAes 
     * @return boolean
     * @Author lhb
     * @CreateTime 2025/6/23 14:15
     */
    @Override
    public boolean authUserPassword(Long userId, String passwordAes) {
        return userAuthMapper.verifyUserAuth(userId, passwordAes) != 0;
    }

    /**
     * @Description: 注册用户凭证
     * @param userId
     * @param passwordAes
     * @return int
     * @Author lhb
     * @CreateTime 2025/6/23 14:37
     */
    @Override
    public int registerUserAuth(Long userId, String passwordAes) {
        return userAuthMapper.insert(userId,passwordAes);
    }

    @Override
    public Long getAllUserNum() {
        return userMapper.getUserNum();
    }

    /**
     * @Description: 模糊匹配获取用户列表
     * @param content
     * @return List<User>
     * @Author lhb
     * @CreateTime 2025/7/1 9:29
     */
    @Override
    public List<User> getUsersByName(String content) {
        return userMapper.getUsersByName(content);
    }

    /**
     * @Description: 根据传入的userIds获取user列表
     * @param userIds
     * @return List<User>
     * @Author lhb
     * @CreateTime 2025/7/1 10:03
     */
    @Override
    public List<User> getUsersByUserIds(List<Long> userIds) {
        return userMapper.getUsersByUserIds(userIds);
    }

    /**
     * @Description: 更新用户密码
     * @param userId
     * @param passwordAes
     * @return int
     * @Author lhb
     * @CreateTime 2025/7/25 17:03
     */
    @Override
    public int updateUserAuth(Long userId, String passwordAes) {
        return userAuthMapper.updateUserAuth(userId, passwordAes);
    }

    /**
     * @Description: 修改密码（含判断逻辑）
     * @param resetPasswordReq
     * @return Result<Object>
     * @Author lhb
     * @CreateTime 2025/7/25 17:03
     */
    @Override
    public Result<Object> resetPassword(ResetPasswordReq resetPasswordReq, String phoneAesDataBase, Long userId) {
        String phone = resetPasswordReq.getPhone();
        String oldPassword = resetPasswordReq.getOldPassword();
        String newPassword = resetPasswordReq.getNewPassword();
        String phoneAes = "";
        String oldPasswordAes = "";
        String newPasswordAes = "";
        try {
            oldPasswordAes = SecureEncryptionUtil.encrypt(oldPassword,authConfig.getPasswordSecret());
            newPasswordAes = SecureEncryptionUtil.encrypt(newPassword,authConfig.getPasswordSecret());
            phoneAes = phoneNumberUtils.encryptPhone(phone);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        if(!Objects.equals(phoneAesDataBase, phoneAes)) {
            throw new IllegalArgumentException("VALIDATION_ERROR：手机号或者密码错误");
        }
        if(userAuthMapper.verifyUserAuth(userId, oldPasswordAes) == 0) {
            throw new IllegalArgumentException("VALIDATION_ERROR：手机号或者密码错误");
        }
        if(userAuthMapper.updateUserAuth(userId, newPasswordAes) == 0) {
            throw new RuntimeException("修改密码异常");
        }
        return Result.success();
    }


    /**
     * @Description: 更换手机号，包含校验逻辑
     * @param resetPhoneReq
     * @param phoneAesDataBase
     * @return Result<Object>
     * @Author lhb
     * @CreateTime 2025/7/26 13:49
     */
    @Override
    public Result<Object> resetPhone(ResetPhoneReq resetPhoneReq, String phoneAesDataBase, Long userId) {
        String oldPhone = resetPhoneReq.getOldPhone();
        String newPhone = resetPhoneReq.getNewPhone();
        String password = resetPhoneReq.getPassword();
        String oldPhoneAes = "";
        String newPhoneAes = "";
        String passwordAes = "";
        try {
            oldPhoneAes = phoneNumberUtils.encryptPhone(oldPhone);
            newPhoneAes = phoneNumberUtils.encryptPhone(newPhone);
            passwordAes = SecureEncryptionUtil.encrypt(password,authConfig.getPasswordSecret());
        } catch (Exception e) {
            throw new RuntimeException("手机号格式错误");
        }
        if(!Objects.equals(phoneAesDataBase, oldPhoneAes)) {
            //非本手机号不能修改
            throw new IllegalArgumentException("VALIDATION_ERROR：手机号或者密码错误");
        }
        if(userAuthMapper.verifyUserAuth(userId, passwordAes) == 0) {
            throw new IllegalArgumentException("VALIDATION_ERROR：手机号或者密码错误");
        }
        User newPhoneUser = getUserByPhoneAes(newPhoneAes);
        if(Objects.nonNull(newPhoneUser)) {
            throw new IllegalArgumentException("VALIDATION_ERROR：该手机号已被注册");
        }
        if(userMapper.resetPhoneAes(userId, newPhoneAes) == 0) {
            throw new RuntimeException("更换手机号过程异常");
        }
        return Result.success();
    }


}
